package com.dh.core.security;

import com.dh.core.config.Constant;
import com.dh.core.config.UserRole;
import com.dh.entity.User;
import com.dh.repository.UserRepository;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

public class ShiroRealm extends AuthorizingRealm {


    @Autowired
    private UserRepository userRepository;


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = usernamePasswordToken.getUsername();
        User user = userRepository.findByUsernameAndDeleted(username, Constant.NOT_DELETE);

        if (user == null) {
            throw new AuthenticationException();
        }
        return new SimpleAuthenticationInfo(new EnhanceUser(user.getUsername(), user.getId(), user.getNickname()), user.getPasswd(), getName());
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        try {
            EnhanceUser shiroAccount =
                (EnhanceUser) principals.fromRealm(getName()).iterator().next();
            User user =
                userRepository.findByUsernameAndDeleted(shiroAccount.getUsername(), Constant.NOT_DELETE);

            if (user != null) {
                SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
                for (UserRole role : UserRole.values()) {
                    if (isInGroup(user.getAccountRole(), role.getId())) {
                        info.addRole(role.toString());
                    }
                }
                return info;
            }
        } catch (Exception e) {
        }
        return null;
    }

    @Override
    protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
        return principals.getPrimaryPrincipal().toString();
    }

    /**
     * 更新用户授权信息缓存.
     */
    public void clearCachedAuthorizationInfo(String principal) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthorizationInfo(principals);
    }

    /**
     * 清除所有用户授权信息缓存.
     */
    public void clearAllCachedAuthorizationInfo() {
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null) {
            for (Object key : cache.keys()) {
                cache.remove(key);
            }
        }
    }

    public static boolean isInGroup(Integer role, Integer group) {
        if (role != null) {
            return 0 != (role & group);
        }
        return false;
    }
}
